package me.hyman.testcustomview.itemTouchHelper.channelsMgr;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import me.hyman.testcustomview.R;
import me.hyman.testcustomview.itemTouchHelper.helper.OnItemMoveListener;
import me.hyman.testcustomview.itemTouchHelper.helper.OnTouchVHListener;
import me.hyman.testcustomview.util.Logger;

/**
 * Created by luluteam on 2016/9/21.
 */
public class ChannelMgrAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnItemMoveListener {

    public static final int TYPE_MY_CHANNEL_HEADER = 0;
    public static final int TYPE_MY_CHANNEL = 1;
    public static final int TYPE_OTHER_CHANNEL_HEADER = 2;
    public static final int TYPE_OTHER_CHANNEL = 3;

    private static final int COUNT_MY_HEADER = 1;
    private static final int COUNT_OTHER_HEADER = 1;

    private Context context;
    private ItemTouchHelper itemTouchHelper;
    private LayoutInflater layoutInflater;
    private List<Channel> myChannelItems;
    private List<Channel> otherChannelItems;

    // 是否处于编辑模式下
    private boolean isInEditMode = false;

    // touch 点击开始时间
    private long startTime;

    // touch 间隔时间，用于分辨是否是 "点击"
    private static final long SPACE_TIME = 100;

    private static final long ANIM_TIME = 360L;


    private OnMyChannelItemClickListener onMyChannelItemClickListener;

    public ChannelMgrAdapter(Context context, ItemTouchHelper itemTouchHelper, List<Channel> myChannels, List<Channel> otherChannels) {
        this.context = context;
        this.itemTouchHelper = itemTouchHelper;
        this.myChannelItems = myChannels;
        this.otherChannelItems = otherChannels;
        layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public int getItemViewType(int position) {
        if(position == 0) {
            return TYPE_MY_CHANNEL_HEADER;
        } else if(position > 0 && position < myChannelItems.size() + 1) {
            return TYPE_MY_CHANNEL;
        } else if(position == myChannelItems.size() + COUNT_MY_HEADER) {
            return TYPE_OTHER_CHANNEL_HEADER;
        } else {
            return TYPE_OTHER_CHANNEL;
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {

        switch (viewType) {
            case TYPE_MY_CHANNEL_HEADER:

                final MyChannelHeaderViewHolder myHeaderHolder = new MyChannelHeaderViewHolder(layoutInflater.inflate(R.layout.item_my_channel_header, parent, false));
                myHeaderHolder.txtBtnEdit.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(isInEditMode) {
                            cancelEditMode((RecyclerView)parent);
                            myHeaderHolder.txtBtnEdit.setText("编辑");

                        } else {
                            beginEditMode((RecyclerView) parent);
                            myHeaderHolder.txtBtnEdit.setText("完成");
                        }
                    }
                });

                return myHeaderHolder;

            case TYPE_MY_CHANNEL:

                final MyChannelViewHolder myHolder = new MyChannelViewHolder(layoutInflater.inflate(R.layout.item_my_channel, parent, false));
                myHolder.txtChannel.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        int position = myHolder.getAdapterPosition();
                        if(isInEditMode) {

                            RecyclerView recyclerview = (RecyclerView) parent;
                            View currentView = recyclerview.getLayoutManager().findViewByPosition(position);
                            View targetView = recyclerview.getLayoutManager().findViewByPosition(myChannelItems.size() + COUNT_MY_HEADER + COUNT_OTHER_HEADER);

                           /* if (recyclerview.indexOfChild(targetView) >= 0) {
                                int targetX, targetY;

                                RecyclerView.LayoutManager manager = recyclerview.getLayoutManager();
                                int spanCount = ((GridLayoutManager) manager).getSpanCount();

                                // 移动后 高度将变化 (我的频道Grid 最后一个item在新的一行第一个)
                                if ((myChannelItems.size() - COUNT_MY_HEADER) % spanCount == 0) {
                                    View preTargetView = recyclerview.getLayoutManager().findViewByPosition(myChannelItems.size() + COUNT_MY_HEADER + COUNT_OTHER_HEADER - 1);
                                    targetX = preTargetView.getLeft();
                                    targetY = preTargetView.getTop();
                                } else {
                                    targetX = targetView.getLeft();
                                    targetY = targetView.getTop();
                                }

                                movMyChannelToOther(position);
                                startAnimation(recyclerview, currentView, targetX, targetY);

                            } else {
                                movMyChannelToOther(position);
                            }*/

                            movMyChannelToOther(position);

                        } else {
                            onMyChannelItemClickListener.onItemClick(position - COUNT_MY_HEADER);
                        }
                    }
                });

                myHolder.txtChannel.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {

                        if(!isInEditMode) {
                            RecyclerView recyclerView = (RecyclerView)parent;
                            beginEditMode(recyclerView);

                            View headerView = recyclerView.getChildAt(0);
                            if(headerView == recyclerView.getLayoutManager().findViewByPosition(0)) {
                                TextView txtEdit = (TextView) headerView.findViewById(R.id.txt_btn_edit);
                                txtEdit.setText("完成");
                            }
                        }

                        itemTouchHelper.startDrag(myHolder);
                        return true;
                    }
                });

                myHolder.txtChannel.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if(isInEditMode) {
                            switch (event.getAction()) {
                                case MotionEvent.ACTION_DOWN:
                                    startTime = System.currentTimeMillis();
                                    break;
                                case MotionEvent.ACTION_HOVER_MOVE:
                                    //当MOVE事件与DOWN事件的触发的间隔时间大于100ms时，
                                    // 则认为是拖拽starDrag，小于100ms不做任何处理
                                    if(System.currentTimeMillis() - startTime > SPACE_TIME) {
                                        itemTouchHelper.startDrag(myHolder);
                                    }
                                    break;
                                case MotionEvent.ACTION_UP:
                                    startTime = 0;
                                    break;
                            }
                        }
                        return false;
                    }
                });

                return myHolder;

            case TYPE_OTHER_CHANNEL_HEADER:

                return new RecyclerView.ViewHolder(layoutInflater.inflate(R.layout.item_other_channel_header, parent, false)) {

                };

            case TYPE_OTHER_CHANNEL:

                final OtherChannelViewHolder otherHolder = new OtherChannelViewHolder(layoutInflater.inflate(R.layout.item_other_channel, parent, false));
                otherHolder.txtChannel.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        // 编辑模式下不让其他频道添加到我的频道操作
                        if(!isInEditMode) {

                            int position = otherHolder.getAdapterPosition();

                            RecyclerView recyclerView = (RecyclerView)parent;
                            RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();

                            View currentView = manager.findViewByPosition(position);
                            // 目标位置的前一个item  即当前MyChannel的最后一个
                            View preTargetView = manager.findViewByPosition(myChannelItems.size() - 1 + COUNT_MY_HEADER);

                            // 如果targetView不在屏幕内,则为-1  此时不需要添加动画,因为此时notifyItemMoved自带一个向目标移动的动画
                            // 如果在屏幕内,则添加一个位移动画
                            /*if (recyclerView.indexOfChild(preTargetView) >= 0) {
                                int targetX = preTargetView.getLeft();
                                int targetY = preTargetView.getTop();

                                int targetPosition = myChannelItems.size() - 1 + COUNT_MY_HEADER + COUNT_OTHER_HEADER;

                                GridLayoutManager gridLayoutManager = ((GridLayoutManager) manager);
                                int spanCount = gridLayoutManager.getSpanCount();
                                // target 在最后一行第一个
                                if ((targetPosition - COUNT_MY_HEADER) % spanCount == 0) {
                                    View targetView = manager.findViewByPosition(targetPosition);
                                    targetX = targetView.getLeft();
                                    targetY = targetView.getTop();
                                } else {
                                    targetX += preTargetView.getWidth();

                                    // 最后一个item可见
                                    if (gridLayoutManager.findLastVisibleItemPosition() == getItemCount() - 1) {
                                        // 最后的item在最后一行第一个位置
                                        if ((getItemCount() - 1 - myChannelItems.size() - COUNT_MY_HEADER - COUNT_OTHER_HEADER) % spanCount == 0) {
                                            // RecyclerView实际高度 > 屏幕高度 && RecyclerView实际高度 < 屏幕高度 + item.height
                                            int firstVisiblePostion = gridLayoutManager.findFirstVisibleItemPosition();
                                            if (firstVisiblePostion == 0) {
                                                // FirstCompletelyVisibleItemPosition == 0 即 内容不满一屏幕 , targetY值不需要变化
                                                // // FirstCompletelyVisibleItemPosition != 0 即 内容满一屏幕 并且 可滑动 , targetY值 + firstItem.getTop
                                                if (gridLayoutManager.findFirstCompletelyVisibleItemPosition() != 0) {
                                                    int offset = (-recyclerView.getChildAt(0).getTop()) - recyclerView.getPaddingTop();
                                                    targetY += offset;
                                                }
                                            } else { // 在这种情况下 并且 RecyclerView高度变化时(即可见第一个item的 position != 0),
                                                // 移动后, targetY值  + 一个item的高度
                                                targetY += preTargetView.getHeight();
                                            }
                                        }
                                    } else {
                                        System.out.println("current--No");
                                    }
                                }

                                // 如果当前位置是otherChannel可见的最后一个
                                // 并且 当前位置不在grid的第一个位置
                                // 并且 目标位置不在grid的第一个位置

                                // 则 需要延迟250秒 notifyItemMove , 这是因为这种情况 , 并不触发ItemAnimator , 会直接刷新界面
                                // 导致我们的位移动画刚开始,就已经notify完毕,引起不同步问题
                                if (position == gridLayoutManager.findLastVisibleItemPosition()
                                        && (position - myChannelItems.size() - COUNT_MY_HEADER - COUNT_OTHER_HEADER) % spanCount != 0
                                        && (targetPosition - COUNT_MY_HEADER) % spanCount != 0) {
                                    moveOtherToMyWithDelay(position);
                                } else {
                                    moveOtherChannelToMy(position);
                                }
                                startAnimation(recyclerView, currentView, targetX, targetY);

                            } else {
                                moveOtherChannelToMy(position);
                            }*/

                            moveOtherChannelToMy(position);

                        }
                    }
                });

                return otherHolder;
        }

        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if(holder instanceof MyChannelHeaderViewHolder) {

            MyChannelHeaderViewHolder headerViewHolder = (MyChannelHeaderViewHolder) holder;
            if(isInEditMode) {
                headerViewHolder.txtBtnEdit.setText("完成");
            } else {
                headerViewHolder.txtBtnEdit.setText("编辑");
            }

        } else if(holder instanceof MyChannelViewHolder) {

            MyChannelViewHolder myHolder = (MyChannelViewHolder) holder;
            myHolder.txtChannel.setText(myChannelItems.get(position - COUNT_MY_HEADER).getText());
            if(isInEditMode) {
                myHolder.imgEdit.setVisibility(View.VISIBLE);
            } else {
                myHolder.imgEdit.setVisibility(View.INVISIBLE);
            }

        } else if(holder instanceof OtherChannelViewHolder) {

            OtherChannelViewHolder otherHolder = (OtherChannelViewHolder) holder;
            otherHolder.txtChannel.setText(otherChannelItems.get(position - myChannelItems.size() - COUNT_MY_HEADER - COUNT_OTHER_HEADER).getText());
        }
    }

    @Override
    public int getItemCount() {
        return myChannelItems.size() + COUNT_MY_HEADER + otherChannelItems.size() + COUNT_OTHER_HEADER;
    }

    /**
     * 我的频道开始拖动排序时调用
     * @param fromPosition
     * @param toPosition
     */
    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        Channel channel = myChannelItems.get(fromPosition - COUNT_MY_HEADER);
        myChannelItems.remove(fromPosition - COUNT_MY_HEADER);
        myChannelItems.add(toPosition - COUNT_MY_HEADER, channel);
        notifyItemMoved(fromPosition, toPosition);
    }

    /**
     * 开启编辑模式
     * @param parent
     */
    private void beginEditMode(RecyclerView parent) {
        isInEditMode = true;

        int visibleChildCount = parent.getChildCount();
        for(int i=0; i<visibleChildCount; i++) {
            View view = parent.getChildAt(i);
            ImageView imgEdit = (ImageView) view.findViewById(R.id.img_edit);
            if(imgEdit != null) {
                imgEdit.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * 关闭编辑模式
     * @param parent
     */
    private void cancelEditMode(RecyclerView parent) {
        isInEditMode = false;

        int visibleChildCount = parent.getChildCount();
        for(int i=0; i<visibleChildCount; i++) {
            View view = parent.getChildAt(i);
            ImageView imgEdit = (ImageView) view.findViewById(R.id.img_edit);
            if(imgEdit != null) {
                imgEdit.setVisibility(View.INVISIBLE);
            }
        }
    }

    private void movMyChannelToOther(int adapterPosition) {

        int position = adapterPosition - COUNT_MY_HEADER;

        if(position > myChannelItems.size() -1) {
            return;
        }

        Channel channel = myChannelItems.get(position);
        myChannelItems.remove(position);
        otherChannelItems.add(0, channel);

        notifyItemMoved(adapterPosition, myChannelItems.size() + COUNT_MY_HEADER);
    }

    private void moveOtherChannelToMy(int adapterPosition) {

        int position = adapterPosition - myChannelItems.size() - COUNT_MY_HEADER - COUNT_OTHER_HEADER;

        if(position > otherChannelItems.size() - 1) {
            return;
        }

        Channel channel = otherChannelItems.get(position);
        otherChannelItems.remove(position);
        myChannelItems.add(channel);

        notifyItemMoved(adapterPosition, myChannelItems.size() -1 + COUNT_MY_HEADER);
    }


    private Handler delayHandler = new Handler();
    /**
     * 其他频道 移动到 我的频道 伴随延迟
     *
     * @param adapterPosition
     */
    private void moveOtherToMyWithDelay(final int adapterPosition) {
        int position = adapterPosition - myChannelItems.size() - COUNT_MY_HEADER - COUNT_OTHER_HEADER;

        Channel channel = otherChannelItems.get(position);
        otherChannelItems.remove(position);
        myChannelItems.add(channel);

        delayHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                notifyItemMoved(adapterPosition, myChannelItems.size() - 1 + COUNT_MY_HEADER);
            }
        }, ANIM_TIME);
    }

    /**
     * 开始增删动画
     */
    private void startAnimation(RecyclerView recyclerView, final View currentView, float targetX, float targetY) {
        final ViewGroup viewGroup = (ViewGroup) recyclerView.getParent();
        final ImageView mirrorView = addMirrorView(viewGroup, recyclerView, currentView);

        Animation animation = getTranslateAnimator(
                targetX - currentView.getLeft(), targetY - currentView.getTop());
        currentView.setVisibility(View.INVISIBLE);
        mirrorView.startAnimation(animation);

        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                viewGroup.removeView(mirrorView);
                if (currentView.getVisibility() == View.INVISIBLE) {
                    currentView.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 添加需要移动的 镜像View
     */
    private ImageView addMirrorView(ViewGroup parent, RecyclerView recyclerView, View view) {
        /**
         * 我们要获取cache首先要通过setDrawingCacheEnable方法开启cache，然后再调用getDrawingCache方法就可以获得view的cache图片了。
         buildDrawingCache方法可以不用调用，因为调用getDrawingCache方法时，若果cache没有建立，系统会自动调用buildDrawingCache方法生成cache。
         若想更新cache, 必须要调用destoryDrawingCache方法把旧的cache销毁，才能建立新的。
         当调用setDrawingCacheEnabled方法设置为false, 系统也会自动把原来的cache销毁。
         */
        view.destroyDrawingCache();
        view.setDrawingCacheEnabled(true);
        final ImageView mirrorView = new ImageView(recyclerView.getContext());
        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
        mirrorView.setImageBitmap(bitmap);
        view.setDrawingCacheEnabled(false);
        int[] locations = new int[2];
        view.getLocationOnScreen(locations);
        int[] parenLocations = new int[2];
        recyclerView.getLocationOnScreen(parenLocations);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(bitmap.getWidth(), bitmap.getHeight());
        params.setMargins(locations[0], locations[1] - parenLocations[1], 0, 0);
        parent.addView(mirrorView, params);

        return mirrorView;
    }

    /**
     * 获取位移动画
     */
    private TranslateAnimation getTranslateAnimator(float targetX, float targetY) {
        TranslateAnimation translateAnimation = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0f,
                Animation.ABSOLUTE, targetX,
                Animation.RELATIVE_TO_SELF, 0f,
                Animation.ABSOLUTE, targetY);
        // RecyclerView默认移动动画250ms 这里设置360ms 是为了防止在位移动画结束后 remove(view)过早 导致闪烁
        translateAnimation.setDuration(ANIM_TIME);
        translateAnimation.setFillAfter(true);
        return translateAnimation;
    }



    public interface OnMyChannelItemClickListener {
        void onItemClick(int position);
    }

    public void setOnMyChannelItemClickListener(OnMyChannelItemClickListener onMyChannelItemClickListener) {
        this.onMyChannelItemClickListener = onMyChannelItemClickListener;
    }

    class MyChannelViewHolder extends RecyclerView.ViewHolder implements OnTouchVHListener {

        TextView txtChannel;
        ImageView imgEdit;

        public MyChannelViewHolder(View itemView) {
            super(itemView);
            txtChannel = (TextView) itemView.findViewById(R.id.txtChannel);
            imgEdit = (ImageView) itemView.findViewById(R.id.img_edit);
        }

        @Override
        public void onItemSelected() {
            // 已在资源文件中设置背景，所以这里可以不设
            txtChannel.setBackgroundResource(R.drawable.bg_channel_p);
        }

        @Override
        public void onItemFinish() {
            txtChannel.setBackgroundResource(R.drawable.bg_channel_n);
        }
    }

    class MyChannelHeaderViewHolder extends RecyclerView.ViewHolder {

        TextView txtBtnEdit;

        public MyChannelHeaderViewHolder(View itemView) {
            super(itemView);
            txtBtnEdit = (TextView) itemView.findViewById(R.id.txt_btn_edit);
        }
    }

    class OtherChannelViewHolder extends RecyclerView.ViewHolder {

        TextView txtChannel;

        public OtherChannelViewHolder(View itemView) {
            super(itemView);
            txtChannel = (TextView) itemView.findViewById(R.id.txtChannel);
        }
    }

}
